﻿using NPOI.SS.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using UIWindows.Commands;
using UIWindows.Enums;
using UIWindows.GlobalStatics;
using UIWindows.Models;
using UIWindows.Models.Devices;
using UIWindows.Tools;
using UIWindows.Tools.Helper;
using UIWindows.Views;
using XingLucifer.Devices;
using XingLucifer.IBase;
using XingLucifer.IBase.Enums;

namespace UIWindows.ViewModels
{
    public class ST5520ViewModel
    {
        public TemporaryStatic Temporary { get; set; }
        public ST5520ParametersModel ST5520 { get; set; }
        public DeviceConfigStatic DeviceConfig { get; set; }
        private SystemConfigStatic _systemConfig;
        private UserConfigStatic _configStatic;
        public ST5520ViewModel(DeviceConfigStatic deviceConfig, SystemConfigStatic systemConfigStatic, UserConfigStatic configStatic, TemporaryStatic temporary)
        {
            DeviceConfig = deviceConfig;
            ST5520 = new ST5520ParametersModel();

            var model = DeviceConfig.ST5520.FirstOrDefault(x => x.IsBeingUsed);
            if (model != null)
            {
                model.UpdateValue(ST5520);
            }
            _systemConfig = systemConfigStatic;
            _configStatic = configStatic;
            Temporary = temporary;
        }

        public DelegateCommand SendCMD => new DelegateCommand(async () =>
        {
            StringBuilder stringBuilder = new StringBuilder();
            if (ST5520.MyGuid != Guid.Empty)
            {
                var modeltest = DeviceConfig.ST5520.FirstOrDefault(x => x.MyGuid == ST5520.MyGuid);
                if (modeltest != null)
                {
                    stringBuilder.Append(ST5520.ContrastObject(modeltest));
                }
            }
            string bl = "true";
            if (!string.IsNullOrEmpty(stringBuilder.ToString()))
            {
                bl = (string)await stringBuilder.ToString().MessageDialogs(MessageLevelType.警告, true, PopUpTypes.Global, Visibility.Visible);
            }
            if (bl != "true") { return; }
            var devices = DeviceConfig.DeviceList.Where(x => x.DeviceType == DeviceTypes.ST5520_ShortCircuit);
            if (devices != null)
            {
                _ = MaterialDesignThemes.Wpf.DialogHost.Show(new Views.Dialogs.LoadingDialogs(), PopUpTypes.Global.ToString()).ConfigureAwait(false);
                #region 命令组包
                StringBuilder cmd = new StringBuilder();
                cmd.Append($":VOLTAGE {ST5520.Voltage};");
                cmd.Append($":MOHM:RANGe {(ST5520.MeasurementRange == "AUTO" ? "AUTO" : $"{ST5520.MeasurementRange}M")};");
                cmd.Append($":SPEed {ST5520.SwitchingSpeed};");
                cmd.Append($":TIMer {ST5520.TestTime:F2};");
                cmd.Append($":DELay {ST5520.ResponseTime:F2};");
                cmd.Append($":COMParator:LIMit {ST5520.ComparatorUp}");
                cmd.Append(ST5520.ComparatorUp == "OFF" ? "," : "E+06,");
                cmd.Append(ST5520.ComparatorDown == "OFF" ? ST5520.ComparatorDown : $"{ST5520.ComparatorDown}E+06");
                cmd.Append($";:COMParator:MODE {ST5520.ComparatorModel}");
                cmd.Append("\r\n");
                #endregion
                StringBuilder erroe = new StringBuilder();
                await Task.Run(() =>
                {
                    CancellationTokenSource cancellationToken = new CancellationTokenSource();
                    foreach (var x in devices)
                    {
                        if (x.Index == 999 || x.Index == 0 || string.IsNullOrEmpty(x.IPCOM)) { return; }
                        ICommunication com = null;
                        if (x.IsSocket)
                        {
                            com = new TCPCom(_systemConfig.SCM.FinsIP, x.IPCOM, x.Port, x.DeviceType, x.Index, x.TaskType, x.ServiceName, cancellationToken, EndianTypes.Modbus_ABCD);
                        }
                        else
                        {
                            com = new SerialPortCom(_systemConfig.SCM.FinsIP, x.IPCOM, x.Port, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One, x.DeviceType, x.Index, x.TaskType, x.ServiceName, cancellationToken, EndianTypes.Modbus_ABCD);
                        }
                        IDevices model = EquipmentFactory.NewSocketDevice(_systemConfig.SCM.FinsIP, x.IPCOM, x.Port, x.DeviceType, x.Index, x.TaskType, x.ServiceName, cancellationToken, com);
                        if (model == null)
                        {
                            return;
                        }
                        bool? bools = model.Open();
                        if (bools != null && (bool)bools)
                        {
                            try
                            {
                                _ = com.Write(Encoding.ASCII.GetBytes(cmd.ToString()));
                                Thread.Sleep(500);
                                com.Write(Encoding.ASCII.GetBytes(":VOLTAGE?\r\n"));
                                byte[] bytes = com.Read(6);
                                string str = Encoding.ASCII.GetString(bytes).Trim();
                                if (str != ST5520.Voltage.ToString())
                                {
                                    erroe.Append($"[{x.IPCOM}] [{x.Port}] 写入失败，请检查串口线是否接对");
                                }
                                model.Close();
                            }
                            catch (Exception ex)
                            {
                                erroe.Append($"[{x.IPCOM}] [{x.Port}] 异常：{ex}");
                            }
                        }
                        else
                        {
                            erroe.Append($"[{x.IPCOM}] [{x.Port}] 链接异常，请检查串口服务器!!!\r\n");
                        }
                    }
                    cancellationToken.Cancel();
                });
                if (!string.IsNullOrEmpty(erroe.ToString()))
                {
                    _ = erroe.ToString().MessageDialogs(MessageLevelType.错误, false, PopUpTypes.Global);
                    return;
                }
                foreach (var item in DeviceConfig.ST5520)
                {
                    item.IsBeingUsed = false;
                }
                if (ST5520.MyGuid == Guid.Empty) 
                {
                    var model = new ST5520ParametersModel();
                    ST5520.UpdateValue(model);
                    Guid guid = Guid.NewGuid();
                    model.MyGuid = guid;
                    model.UpdateTime = DateTime.Now;
                    model.UpdateName = _configStatic.LoginUser.Name;
                    model.IsBeingUsed = true;
                    DeviceConfig.ST5520.Add(model);
                }
                else
                {
                    var model = DeviceConfig.ST5520.FirstOrDefault(x => x.MyGuid == ST5520.MyGuid);
                    if (model != null)
                    {
                        model.UpdateTime = DateTime.Now;
                        model.UpdateName = _configStatic.LoginUser.Name;
                        model.IsBeingUsed = true;
                        ST5520.UpdateValue(model);
                    }
                }
                DeviceConfig.SaveST5520();
                _ = "写入成功!!!".MessageDialogs(MessageLevelType.成功, false, PopUpTypes.Global);
            }
        }, Enums.AuthorityTypes.工艺_参照);

        public DelegateCommand Empty => new DelegateCommand(() => new ST5520ParametersModel().UpdateValue(ST5520), Enums.AuthorityTypes.工艺_参照);

        public DelegateCommand Delete => new DelegateCommand(async () =>
        {
            var model = DeviceConfig.ST5520.FirstOrDefault(x => x.MyGuid == ST5520.MyGuid);
            if (model != null
            && (((string)await $"ST5520 [{ST5520.Name}] 二次确认是否删除".MessageDialogs(MessageLevelType.警告, true, PopUpTypes.Global, Visibility.Visible)) != "true"))
            {
                DeviceConfig.ST5520.Remove(model);
                new ST5520ParametersModel().UpdateValue(ST5520);
                DeviceConfig.SaveST5520();
            }
        }, Enums.AuthorityTypes.工艺_参照);

        public DelegateCommand<ST5520ParametersModel> MouseDoubleClick => new DelegateCommand<ST5520ParametersModel>(sender =>
        {
            if (sender == null) { return; }
            sender.UpdateValue(ST5520);
        }, Enums.AuthorityTypes.工艺_参照);
    }
}
